﻿using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;

namespace DotNetExtensions.Core.Extensions
{
    public static class JTokenExtensions
    {
        public static bool TryGetValue(this JToken token, string key, Type type, out object value, bool isIgnoreCase = false)
        {
            
            value = null;
            if (token.Type == JTokenType.Null) return false;
            if (string.IsNullOrEmpty(key)) return false;
            string[] keys = key.Split('.');
            token = Get(token, keys[0], isIgnoreCase);
            for (int i = 1; i < keys.Length; i++)
            {
                token = Get(token, keys[i], isIgnoreCase);
            }
            value = token.ToObject(type);
            return true;
        }
        public static bool TryGetValue<T>(this JToken token, string key, out T value, bool isIgnoreCase = false)
        {
            Type type = typeof(T);
            value = default(T);
            if (token.Type == JTokenType.Null) return false;
            if (string.IsNullOrEmpty(key)) return false;
            string[] keys = key.Split('.');
            token = Get(token, keys[0], isIgnoreCase);
            for (int i = 1; i < keys.Length; i++)
            {
                token = Get(token, keys[i], isIgnoreCase);
            }
            value = (T)token.ToObject(type);
            return true;
        }

        public static JToken Get(JToken token, string key, bool isIgnoreCase = false)
        {
            if (token.Type == JTokenType.Array)
            {
                Regex regex = new Regex(@"\[(\d)\]");
                var match = regex.Match(key);
                if (!match.Success) throw new Exception($"不存在Key={key}");
                string indexStr = match.Groups[0].Value;
                int index = int.Parse(indexStr);
                return (token as JArray)[index];
            }
            else if (token.Type == JTokenType.Object)
            {
                if (isIgnoreCase)
                {
                    List<string> keys = (token as JObject).Properties().Select(x => x.Name).ToList();
                    Dictionary<string, string> keyMaps = new Dictionary<string, string>();
                    foreach (var item in keys)
                    {
                        keyMaps.Add(item.ToLower(), item);
                    }
                    return token[keyMaps[key]];
                }
                else
                {
                    return token[key];
                }
            }
            throw new Exception($"JSON中不存在Key={key}");
        }
    }
}
